using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace ProceduralPrimitivesUtil
{
	[ExecuteInEditMode]
	public abstract class PPBase : MonoBehaviour
	{
		protected List<Vector3> m_vertices = new List<Vector3>();

		protected List<int> m_triangles = new List<int>();

		protected List<Vector3> m_normals = new List<Vector3>();

		protected List<Vector2> m_uv = new List<Vector2>();

		private bool m_dirty;

		private MeshFilter m_meshFilter;

		protected Mesh m_mesh;

		public Vector3 pivotOffset;

		public Vector3 rotation;

		protected Quaternion m_rotation;

		public bool isDirty => m_dirty;

		public Mesh mesh => m_mesh;

		public static float PointLineDistance(Vector3 vp, Vector3 v)
		{
			return Vector3.Cross(vp, v).magnitude / v.magnitude;
		}

		public static float PointLineProjectionn(Vector3 vp, Vector3 v)
		{
			return Vector3.Dot(vp, v) / v.magnitude;
		}

		protected void CreateTriangle(Vector3 p0, Vector3 p1, Vector3 p2)
		{
			int count = m_vertices.Count;
			Vector3 normalized = Vector3.Cross(p1 - p0, p2 - p0).normalized;
			m_vertices.Add(p0);
			m_vertices.Add(p1);
			m_vertices.Add(p2);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			m_triangles.Add(count);
			m_triangles.Add(count + 1);
			m_triangles.Add(count + 2);
		}

		protected void CreateTriangle(Vector3 p0, Vector3 p1, Vector3 p2, Vector2 p0uv, Vector2 p1uv, Vector2 p2uv)
		{
			int count = m_vertices.Count;
			Vector3 normalized = Vector3.Cross(p1 - p0, p2 - p0).normalized;
			m_vertices.Add(p0);
			m_vertices.Add(p1);
			m_vertices.Add(p2);
			m_uv.Add(p0uv);
			m_uv.Add(p1uv);
			m_uv.Add(p2uv);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			m_triangles.Add(count);
			m_triangles.Add(count + 1);
			m_triangles.Add(count + 2);
		}

		protected void CreateQuad(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
		{
			int count = m_vertices.Count;
			Vector3 normalized = Vector3.Cross(p2 - p0, p3 - p1).normalized;
			m_vertices.Add(p0);
			m_vertices.Add(p1);
			m_vertices.Add(p2);
			m_vertices.Add(p3);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			int[] array = new int[4]
			{
				count,
				count + 1,
				count + 2,
				count + 3
			};
			m_triangles.Add(array[0]);
			m_triangles.Add(array[1]);
			m_triangles.Add(array[2]);
			m_triangles.Add(array[2]);
			m_triangles.Add(array[3]);
			m_triangles.Add(array[0]);
		}

		protected void CreateQuad(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, Vector2 p0uv, Vector2 p1uv, Vector2 p2uv, Vector2 p3uv)
		{
			int count = m_vertices.Count;
			Vector3 normalized = Vector3.Cross(p2 - p0, p3 - p1).normalized;
			m_vertices.Add(p0);
			m_vertices.Add(p1);
			m_vertices.Add(p2);
			m_vertices.Add(p3);
			m_uv.Add(p0uv);
			m_uv.Add(p1uv);
			m_uv.Add(p2uv);
			m_uv.Add(p3uv);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			m_normals.Add(normalized);
			int[] array = new int[4]
			{
				count,
				count + 1,
				count + 2,
				count + 3
			};
			m_triangles.Add(array[0]);
			m_triangles.Add(array[1]);
			m_triangles.Add(array[2]);
			m_triangles.Add(array[2]);
			m_triangles.Add(array[3]);
			m_triangles.Add(array[0]);
		}

		protected void CreateTriangle(Vector3 center, Vector3 forward, Vector3 right, float width, float length, float offset, int seg, bool generateUV, bool realWorldMapSize, bool flip)
		{
			CreateTriangle(center, forward, right, width, length, offset, seg, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip);
		}

		protected void CreateTriangle(Vector3 center, Vector3 forward, Vector3 right, float width, float length, float offset, int seg, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip)
		{
			Vector3 normalized = Vector3.Cross(forward, right).normalized;
			float num = length * 0.5f;
			float num2 = width * 0.5f;
			float num3 = 0f;
			if (offset < 0f - num2)
			{
				num3 = (offset + num2) * 0.5f;
			}
			else if (offset > num2)
			{
				num3 = (offset - num2) * 0.5f;
			}
			Vector3 vector = center + right * (0f - num2 - num3) - forward * num;
			Vector3 p = center + right * (offset - num3) + forward * num;
			Vector3 vector2 = center + right * (num2 - num3) - forward * num;
			if (realWorldMapSize)
			{
				uvTiling.x *= width;
				uvTiling.y *= length;
			}
			if (flip)
			{
				CreateTriangle(vector2, p, vector, -normalized, seg, generateUV, uvOffset, uvTiling);
			}
			else
			{
				CreateTriangle(vector, p, vector2, normalized, seg, generateUV, uvOffset, uvTiling);
			}
		}

		protected void CreateTriangle(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 normal, int seg, bool generateUV, Vector2 uvOffset, Vector2 uvTiling)
		{
			int count = m_vertices.Count;
			Vector3 vector = (p1 - p0) / seg;
			Vector3 vector2 = (p2 - p0) / seg;
			if (generateUV)
			{
				Vector2 vector3 = Vector2.right * uvTiling.x / seg;
				Vector2 vector4 = default(Vector2);
				vector4.x = PointLineProjectionn(vector, vector2) / vector2.magnitude * uvTiling.x / (float)seg;
				vector4.y = uvTiling.y / (float)seg;
				for (int i = 0; i <= seg; i++)
				{
					for (int j = 0; j <= seg - i; j++)
					{
						m_vertices.Add(p0 + vector * i + vector2 * j);
						m_normals.Add(normal);
						m_uv.Add(uvOffset + vector4 * i + vector3 * j);
					}
				}
			}
			else
			{
				for (int k = 0; k <= seg; k++)
				{
					for (int l = 0; l <= seg - k; l++)
					{
						m_vertices.Add(p0 + vector * k + vector2 * l);
						m_normals.Add(normal);
					}
				}
			}
			int num = 0;
			for (int m = 0; m < seg; m++)
			{
				int num2 = seg + 1 - m;
				for (int n = 0; n < seg - m - 1; n++)
				{
					m_triangles.Add(count + num + n);
					m_triangles.Add(count + num + num2 + n);
					m_triangles.Add(count + num + n + 1);
					m_triangles.Add(count + num + n + 1);
					m_triangles.Add(count + num + num2 + n);
					m_triangles.Add(count + num + num2 + n + 1);
				}
				m_triangles.Add(count + num + seg - m - 1);
				m_triangles.Add(count + num + num2 + seg - m - 1);
				m_triangles.Add(count + num + seg - m);
				num += num2;
			}
		}

		protected void CreateTriangle(Vector3 center, Vector3 forward, Vector3 right, float width, float length, float offset, int segW, int segL, bool generateUV, bool realWorldMapSize, bool flip)
		{
			CreateTriangle(center, forward, right, width, length, offset, segW, segL, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip);
		}

		protected void CreateTriangle(Vector3 center, Vector3 forward, Vector3 right, float width, float length, float offset, int segW, int segL, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip)
		{
			Vector3 normalized = Vector3.Cross(forward, right).normalized;
			float num = length * 0.5f;
			float num2 = width * 0.5f;
			float num3 = 0f;
			if (offset < 0f - num2)
			{
				num3 = (offset + num2) * 0.5f;
			}
			else if (offset > num2)
			{
				num3 = (offset - num2) * 0.5f;
			}
			Vector3 vector = center + right * (0f - num2 - num3) - forward * num;
			Vector3 p = center + right * (offset - num3) + forward * num;
			Vector3 vector2 = center + right * (num2 - num3) - forward * num;
			if (realWorldMapSize)
			{
				uvTiling.x *= width;
				uvTiling.y *= length;
			}
			if (flip)
			{
				CreateTriangle(vector2, p, vector, -normalized, segW, segL, generateUV, uvOffset, uvTiling);
			}
			else
			{
				CreateTriangle(vector, p, vector2, normalized, segW, segL, generateUV, uvOffset, uvTiling);
			}
		}

		protected void CreateTriangle(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 normal, int segW, int segL, bool generateUV, Vector2 uvOffset, Vector2 uvTiling)
		{
			int count = m_vertices.Count;
			Vector3 vector = (p2 - p0) / segW;
			if (generateUV)
			{
				Vector2 vector2 = Vector2.right * uvTiling.x / segW;
				Vector2 vector3 = Vector2.down * uvTiling.y / segL;
				for (int i = 0; i <= segW; i++)
				{
					Vector3 vector4 = p0 + vector * i;
					for (int j = 0; j <= segL; j++)
					{
						Vector3 item = p1 * (segL - j) / segL + vector4 * j / segL;
						m_vertices.Add(item);
						m_normals.Add(normal);
						m_uv.Add(uvOffset + vector2 * i + vector3 * j);
					}
				}
			}
			else
			{
				for (int k = 0; k <= segW; k++)
				{
					Vector3 vector5 = p0 + vector * k;
					for (int l = 0; l <= segL; l++)
					{
						Vector3 item2 = p1 * (segL - l) / segL + vector5 * l / segL;
						m_vertices.Add(item2);
						m_normals.Add(normal);
					}
				}
			}
			for (int m = 0; m < segW; m++)
			{
				m_triangles.Add(count + (segL + 1) * (m + 1) + 1);
				m_triangles.Add(count + (segL + 1) * m + 1);
				m_triangles.Add(count + (segL + 1) * m);
				for (int n = 1; n < segL; n++)
				{
					m_triangles.Add(count + (segL + 1) * m + n);
					m_triangles.Add(count + (segL + 1) * (m + 1) + n);
					m_triangles.Add(count + (segL + 1) * (m + 1) + (n + 1));
					m_triangles.Add(count + (segL + 1) * (m + 1) + (n + 1));
					m_triangles.Add(count + (segL + 1) * m + (n + 1));
					m_triangles.Add(count + (segL + 1) * m + n);
				}
			}
		}

		protected void CreatePlane(Vector3 center, Vector3 forward, Vector3 right, float width, float length, int segW, int segL, bool generateUV, bool realWorldMapSize, bool flip)
		{
			CreatePlane(center, forward, right, width, length, segW, segL, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip);
		}

		protected void CreatePlane(Vector3 center, Vector3 forward, Vector3 right, float width, float length, int segW, int segL, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip)
		{
			Vector3 normalized = Vector3.Cross(forward, right).normalized;
			float num = length * 0.5f;
			float num2 = width * 0.5f;
			Vector3 vector = center - right * num2 - forward * num;
			Vector3 vector2 = center - right * num2 + forward * num;
			Vector3 vector3 = center + right * num2 + forward * num;
			Vector3 vector4 = center + right * num2 - forward * num;
			if (realWorldMapSize)
			{
				uvTiling.x *= width;
				uvTiling.y *= length;
			}
			if (flip)
			{
				CreatePlane(vector4, vector3, vector2, vector, -normalized, segW, segL, generateUV, uvOffset, uvTiling);
			}
			else
			{
				CreatePlane(vector, vector2, vector3, vector4, normalized, segW, segL, generateUV, uvOffset, uvTiling);
			}
		}

		protected void CreatePlane(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 normal, int segW, int segL, bool generateUV, Vector2 uvOffset, Vector2 uvTiling)
		{
			int count = m_vertices.Count;
			Vector3 vector = (p3 - p0) / segW;
			Vector3 vector2 = (p1 - p0) / segL;
			if (generateUV)
			{
				Vector2 vector3 = Vector2.right * uvTiling.x / segW;
				Vector2 vector4 = Vector2.up * uvTiling.y / segL;
				for (int i = 0; i <= segW; i++)
				{
					for (int j = 0; j <= segL; j++)
					{
						m_vertices.Add(p0 + vector * i + vector2 * j);
						m_normals.Add(normal);
						m_uv.Add(uvOffset + vector3 * i + vector4 * j);
					}
				}
			}
			else
			{
				for (int k = 0; k <= segW; k++)
				{
					for (int l = 0; l <= segL; l++)
					{
						m_vertices.Add(p0 + vector * k + vector2 * l);
						m_normals.Add(normal);
					}
				}
			}
			for (int m = 0; m < segW; m++)
			{
				for (int n = 0; n < segL; n++)
				{
					int[] array = new int[4]
					{
						count + (segL + 1) * m + n,
						count + (segL + 1) * m + (n + 1),
						count + (segL + 1) * (m + 1) + (n + 1),
						count + (segL + 1) * (m + 1) + n
					};
					m_triangles.Add(array[0]);
					m_triangles.Add(array[1]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[3]);
					m_triangles.Add(array[0]);
				}
			}
		}

		protected void CreateTrapezoid(Vector3 center, Vector3 forward, Vector3 right, float width1, float width2, float length, float offset, int segW, int segL, bool generateUV, bool realWorldMapSize, bool flip)
		{
			CreateTrapezoid(center, forward, right, width1, width2, length, offset, segW, segL, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip);
		}

		protected void CreateTrapezoid(Vector3 center, Vector3 forward, Vector3 right, float width1, float width2, float length, float offset, int segW, int segL, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip)
		{
			Vector3 normalized = Vector3.Cross(forward, right).normalized;
			float num = length * 0.5f;
			float num2 = width1 * 0.5f;
			float num3 = width2 * 0.5f;
			float num4 = 0f;
			if (width1 > width2)
			{
				if (offset + num3 > num2)
				{
					num4 = (offset + num3 - num2) * 0.5f;
				}
				else if (offset - num3 < 0f - num2)
				{
					num4 = (offset - num3 + num2) * 0.5f;
				}
			}
			else if (offset + num2 > num3)
			{
				num4 = (offset + num2 - num3) * 0.5f;
			}
			else if (offset - num2 < 0f - num3)
			{
				num4 = (offset - num2 + num3) * 0.5f;
			}
			Vector3 vector = center + right * (0f - num2 - num4) - forward * num;
			Vector3 vector2 = center + right * (0f - num3 + offset - num4) + forward * num;
			Vector3 vector3 = center + right * (num3 + offset - num4) + forward * num;
			Vector3 vector4 = center + right * (num2 - num4) - forward * num;
			if (realWorldMapSize)
			{
				uvTiling.x *= (width1 + width2) * 0.5f;
				uvTiling.y *= length;
			}
			if (flip)
			{
				CreateTrapezoid(vector4, vector3, vector2, vector, -normalized, segW, segL, generateUV, uvOffset, uvTiling);
			}
			else
			{
				CreateTrapezoid(vector, vector2, vector3, vector4, normalized, segW, segL, generateUV, uvOffset, uvTiling);
			}
		}

		protected void CreateTrapezoid(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 normal, int segW, int segL, bool generateUV, Vector2 uvOffset, Vector2 uvTiling)
		{
			int count = m_vertices.Count;
			Vector3 vector = (p2 - p1) / segW;
			Vector3 vector2 = (p3 - p0) / segW;
			if (generateUV)
			{
				Vector2 vector3 = Vector2.right * uvTiling.x / segW;
				Vector2 vector4 = Vector2.down * uvTiling.y / segL;
				for (int i = 0; i <= segW; i++)
				{
					Vector3 vector5 = p1 + vector * i;
					Vector3 vector6 = p0 + vector2 * i;
					for (int j = 0; j <= segL; j++)
					{
						Vector3 item = vector5 * j / segL + vector6 * (segL - j) / segL;
						m_vertices.Add(item);
						m_normals.Add(normal);
						m_uv.Add(uvOffset + vector3 * i + vector4 * (segL - j));
					}
				}
			}
			else
			{
				for (int k = 0; k <= segW; k++)
				{
					Vector3 vector7 = p1 + vector * k;
					Vector3 vector8 = p0 + vector2 * k;
					for (int l = 0; l <= segL; l++)
					{
						Vector3 item2 = vector7 * l / segL + vector8 * (segL - l) / segL;
						m_vertices.Add(item2);
						m_normals.Add(normal);
					}
				}
			}
			for (int m = 0; m < segW; m++)
			{
				for (int n = 0; n < segL; n++)
				{
					int[] array = new int[4]
					{
						count + (segL + 1) * m + n,
						count + (segL + 1) * m + (n + 1),
						count + (segL + 1) * (m + 1) + (n + 1),
						count + (segL + 1) * (m + 1) + n
					};
					m_triangles.Add(array[0]);
					m_triangles.Add(array[1]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[3]);
					m_triangles.Add(array[0]);
				}
			}
		}

		protected void CreateCircle(Vector3 center, Vector3 forward, Vector3 right, float radius, int sides, int seg, bool generateUV, bool realWorldMapSize, bool flip)
		{
			CreateCircle(center, forward, right, radius, sides, seg, sliceOn: false, 0f, 360f, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip);
		}

		protected void CreateCircle(Vector3 center, Vector3 forward, Vector3 right, float radius, int sides, int seg, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, bool flip)
		{
			CreateCircle(center, forward, right, radius, sides, seg, sliceOn, sliceFrom, sliceTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip);
		}

		protected void CreateCircle(Vector3 center, Vector3 forward, Vector3 right, float radius, int sides, int seg, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip)
		{
			if (radius < 0.0001f)
			{
				return;
			}
			Vector3 vector = Vector3.Cross(forward, right).normalized;
			Vector2[] array = new Vector2[sides + 1];
			Vector3[] array2 = new Vector3[sides + 1];
			if (!sliceOn)
			{
				sliceFrom = 0f;
				sliceTo = 360f;
			}
			float num = sliceFrom * (MathF.PI / 180f);
			float num2 = (sliceTo - sliceFrom) * (MathF.PI / 180f) / (float)sides;
			for (int i = 0; i <= sides; i++)
			{
				float f = num + num2 * (float)i;
				array[i].x = Mathf.Sin(f);
				array[i].y = Mathf.Cos(f);
				array2[i] = center + (forward * array[i].y + right * array[i].x) * radius;
			}
			Vector2[] array3 = (generateUV ? array : null);
			if (realWorldMapSize)
			{
				uvTiling *= radius * 2f;
			}
			if (flip)
			{
				vector = -vector;
				array2 = array2.Reverse().ToArray();
				if (array3 != null)
				{
					array3 = array3.Reverse().ToArray();
				}
			}
			CreateCircle(array2, array3, center, vector, seg, uvOffset, uvTiling);
		}

		protected void CreateHemiCircle(Vector3 center, Vector3 forward, Vector3 right, float radius, int sides, int seg, bool hemiCircle, float cutFrom, float cutTo, bool generateUV, bool realWorldMapSize, bool flip, bool isSector = false)
		{
			CreateHemiCircle(center, forward, right, radius, sides, seg, hemiCircle, cutFrom, cutTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip, isSector);
		}

		protected void CreateHemiCircle(Vector3 center, Vector3 forward, Vector3 right, float radius, int sides, int seg, bool hemiCircle, float cutFrom, float cutTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool isSector = false)
		{
			if (radius < 0.0001f)
			{
				return;
			}
			Vector3 vector = Vector3.Cross(forward, right).normalized;
			List<Vector2> list = new List<Vector2>();
			List<Vector3> list2 = new List<Vector3>();
			float num = MathF.PI / (float)sides;
			Vector3 vector2 = default(Vector3);
			float centerUVOffset = 0f;
			if (hemiCircle)
			{
				float num2 = 0f;
				Vector2 item = new Vector2(Mathf.Sin(cutFrom), 0f - Mathf.Cos(cutFrom));
				Vector2 item2 = new Vector2(Mathf.Sin(cutTo), 0f - Mathf.Cos(cutTo));
				if (cutFrom < MathF.PI / 2f)
				{
					if (isSector)
					{
						num2 = num * (float)(Mathf.FloorToInt(cutFrom / num) + 1);
					}
					else
					{
						for (; num2 < cutFrom; num2 += num)
						{
							Vector2 vector3 = new Vector2(Mathf.Sin(num2), 0f - Mathf.Cos(num2));
							list.Add(vector3 * (item.y / vector3.y));
							list2.Add(center + (forward * vector3.y + right * vector3.x) * (radius * (item.y / vector3.y)));
						}
					}
					list.Add(item);
					list2.Add(center + (forward * item.y + right * item.x) * radius);
					for (; num2 < MathF.PI / 2f && num2 < cutTo; num2 += num)
					{
						Vector2 item3 = new Vector2(Mathf.Sin(num2), 0f - Mathf.Cos(num2));
						list.Add(item3);
						list2.Add(center + (forward * item3.y + right * item3.x) * radius);
					}
				}
				else
				{
					list.Add(item);
					list2.Add(center + (forward * item.y + right * item.x) * radius);
					if (!isSector)
					{
						centerUVOffset = item.y * 0.5f;
						vector2 = forward * (item.y * radius);
					}
					num2 = num * (float)(Mathf.FloorToInt(cutFrom / num) + 1);
				}
				if (cutTo > MathF.PI / 2f)
				{
					for (; num2 < cutTo; num2 += num)
					{
						Vector2 item4 = new Vector2(Mathf.Sin(num2), 0f - Mathf.Cos(num2));
						list.Add(item4);
						list2.Add(center + (forward * item4.y + right * item4.x) * radius);
					}
					list.Add(item2);
					list2.Add(center + (forward * item2.y + right * item2.x) * radius);
					if (!isSector)
					{
						for (; num2 <= MathF.PI; num2 += num)
						{
							Vector2 vector4 = new Vector2(Mathf.Sin(num2), 0f - Mathf.Cos(num2));
							list.Add(vector4 * (item2.y / vector4.y));
							list2.Add(center + (forward * vector4.y + right * vector4.x) * (radius * (item2.y / vector4.y)));
						}
					}
				}
				else
				{
					list.Add(item2);
					list2.Add(center + (forward * item2.y + right * item2.x) * radius);
					if (!isSector)
					{
						centerUVOffset = item2.y * 0.5f;
						vector2 = forward * (item2.y * radius);
					}
				}
			}
			else
			{
				for (int i = 0; i <= sides; i++)
				{
					Vector2 item5 = new Vector2(Mathf.Sin(num * (float)i), 0f - Mathf.Cos(num * (float)i));
					list.Add(item5);
					list2.Add(center + (forward * item5.y + right * item5.x) * radius);
				}
			}
			Vector2[] array = (generateUV ? list.ToArray() : null);
			if (realWorldMapSize)
			{
				uvTiling *= radius * 2f;
			}
			if (flip)
			{
				vector = -vector;
				list2.Reverse();
				if (array != null)
				{
					array = array.Reverse().ToArray();
				}
			}
			CreateCircle(list2.ToArray(), array, center + vector2, -vector, seg, uvOffset, uvTiling, centerUVOffset);
		}

		protected void CreateCircle(Vector3[] points, Vector2[] uvs, Vector3 center, Vector3 normal, int seg, Vector2 uvOffset, Vector2 uvTiling, float centerUVOffset = 0f)
		{
			int count = m_vertices.Count;
			if (uvs != null)
			{
				Vector2 vector = new Vector2(0.5f, 0.5f + centerUVOffset);
				m_vertices.Add(center);
				m_normals.Add(normal);
				m_uv.Add(uvOffset + vector);
				for (int i = 0; i < points.Length; i++)
				{
					Vector3 vector2 = (points[i] - center) / seg;
					Vector2 vector3 = uvs[i] * 0.5f;
					vector3.y -= centerUVOffset;
					vector3.x *= uvTiling.x / (float)seg;
					vector3.y *= uvTiling.y / (float)seg;
					for (int j = 1; j <= seg; j++)
					{
						m_vertices.Add(center + vector2 * j);
						m_normals.Add(normal);
						m_uv.Add(uvOffset + vector + vector3 * j);
					}
				}
			}
			else
			{
				m_vertices.Add(center);
				m_normals.Add(normal);
				for (int k = 0; k < points.Length; k++)
				{
					Vector3 vector4 = (points[k] - center) / seg;
					for (int l = 1; l <= seg; l++)
					{
						m_vertices.Add(center + vector4 * l);
						m_normals.Add(normal);
					}
				}
			}
			for (int m = 0; m < points.Length - 1; m++)
			{
				m_triangles.Add(count);
				m_triangles.Add(count + seg * m + 1);
				m_triangles.Add(count + seg * (m + 1) + 1);
				for (int n = 1; n < seg; n++)
				{
					int[] array = new int[4]
					{
						count + seg * m + n,
						count + seg * m + (n + 1),
						count + seg * (m + 1) + (n + 1),
						count + seg * (m + 1) + n
					};
					m_triangles.Add(array[0]);
					m_triangles.Add(array[1]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[3]);
					m_triangles.Add(array[0]);
				}
			}
		}

		protected void CreateRing(Vector3 center, Vector3 forward, Vector3 right, float radius1, float radius2, int sides, int seg, bool generateUV, bool realWorldMapSize, bool flip)
		{
			CreateRing(center, forward, right, radius1, radius2, sides, seg, sliceOn: false, 0f, 360f, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip);
		}

		protected void CreateRing(Vector3 center, Vector3 forward, Vector3 right, float radius1, float radius2, int sides, int seg, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, bool flip)
		{
			CreateRing(center, forward, right, radius1, radius2, sides, seg, sliceOn, sliceFrom, sliceTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip);
		}

		protected void CreateRing(Vector3 center, Vector3 forward, Vector3 right, float radius1, float radius2, int sides, int seg, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip)
		{
			if (radius1 + radius2 < 0.0001f)
			{
				return;
			}
			Vector3 vector = Vector3.Cross(forward, right).normalized;
			Vector2[] array = new Vector2[sides + 1];
			Vector3[] array2 = new Vector3[sides + 1];
			if (!sliceOn)
			{
				sliceFrom = 0f;
				sliceTo = 360f;
			}
			float num = sliceFrom * (MathF.PI / 180f);
			float num2 = (sliceTo - sliceFrom) * (MathF.PI / 180f) / (float)sides;
			for (int i = 0; i <= sides; i++)
			{
				float f = num + num2 * (float)i;
				array[i].x = Mathf.Sin(f);
				array[i].y = Mathf.Cos(f);
				array2[i] = center + (forward * array[i].y + right * array[i].x) * radius1;
			}
			Vector2[] array3 = (generateUV ? array : null);
			if (realWorldMapSize)
			{
				uvTiling *= radius1 * 2f;
			}
			if (flip)
			{
				vector = -vector;
				array2 = array2.Reverse().ToArray();
				if (array3 != null)
				{
					array3 = array3.Reverse().ToArray();
				}
			}
			CreateRing(array2, array3, center, vector, radius2 / radius1, seg, uvOffset, uvTiling);
		}

		protected void CreateRing(Vector3[] points, Vector2[] uvs, Vector3 center, Vector3 normal, float ratio, int seg, Vector2 uvOffset, Vector2 uvTiling, float centerUVOffset = 0f)
		{
			int count = m_vertices.Count;
			if (uvs != null)
			{
				Vector2 vector = new Vector2(0.5f, 0.5f + centerUVOffset);
				for (int i = 0; i < points.Length; i++)
				{
					Vector3 vector2 = (points[i] - center) * ratio;
					Vector3 vector3 = (points[i] - (center + vector2)) / seg;
					Vector2 vector4 = uvs[i] * ratio * 0.5f;
					vector4.x *= uvTiling.x;
					vector4.y *= uvTiling.y;
					Vector2 vector5 = (uvs[i] - uvs[i] * ratio) * 0.5f;
					vector5.x *= uvTiling.x / (float)seg;
					vector5.y *= uvTiling.y / (float)seg;
					for (int j = 0; j <= seg; j++)
					{
						m_vertices.Add(center + vector2 + vector3 * j);
						m_normals.Add(normal);
						m_uv.Add(vector + uvOffset + vector4 + vector5 * j);
					}
				}
			}
			else
			{
				for (int k = 0; k < points.Length; k++)
				{
					Vector3 vector6 = (points[k] - center) * ratio;
					Vector3 vector7 = (points[k] - (center + vector6)) / seg;
					for (int l = 0; l <= seg; l++)
					{
						m_vertices.Add(center + vector6 + vector7 * l);
						m_normals.Add(normal);
					}
				}
			}
			for (int m = 0; m < points.Length - 1; m++)
			{
				for (int n = 0; n < seg; n++)
				{
					int[] array = new int[4]
					{
						count + (seg + 1) * m + n,
						count + (seg + 1) * m + (n + 1),
						count + (seg + 1) * (m + 1) + (n + 1),
						count + (seg + 1) * (m + 1) + n
					};
					m_triangles.Add(array[0]);
					m_triangles.Add(array[1]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[3]);
					m_triangles.Add(array[0]);
				}
			}
		}

		protected void CreateHemiRing(Vector3 center, Vector3 forward, Vector3 right, float radius1, float radius2, int sides, int seg, bool hemiCircle, float cutFrom, float cutTo, bool generateUV, bool realWorldMapSize, bool flip, bool isSector = false)
		{
			CreateHemiRing(center, forward, right, radius1, radius2, sides, seg, hemiCircle, cutFrom, cutTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip, isSector);
		}

		protected void CreateHemiRing(Vector3 center, Vector3 forward, Vector3 right, float radius1, float radius2, int sides, int seg, bool hemiCircle, float cutFrom, float cutTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool isSector = false)
		{
			if (radius1 + radius2 < 0.0001f)
			{
				return;
			}
			Vector3 vector = Vector3.Cross(forward, right).normalized;
			List<Vector2> list = new List<Vector2>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<Vector3> list4 = new List<Vector3>();
			float num = MathF.PI / (float)sides;
			float num2 = radius2 / radius1;
			Vector3 vector2 = default(Vector3);
			float centerUVOffset = 0f;
			if (hemiCircle)
			{
				Vector2 vector3 = default(Vector2);
				Vector3 vector4 = default(Vector3);
				float num3 = 0f;
				Vector2 vector5 = new Vector2(Mathf.Sin(cutFrom), 0f - Mathf.Cos(cutFrom));
				Vector2 vector6 = new Vector2(Mathf.Sin(cutTo), 0f - Mathf.Cos(cutTo));
				float num4 = Mathf.Acos(Mathf.Clamp((0f - vector5.y) / num2, -1f, 1f));
				float num5 = Mathf.Acos(Mathf.Clamp((0f - vector6.y) / num2, -1f, 1f));
				Vector2 vector7 = new Vector2(Mathf.Sin(num4), 0f - Mathf.Cos(num4));
				Vector2 vector8 = new Vector2(Mathf.Sin(num5), 0f - Mathf.Cos(num5));
				if (cutFrom < MathF.PI / 2f)
				{
					float num7;
					if (isSector)
					{
						num3 = num * (float)(Mathf.FloorToInt(cutFrom / num) + 1);
					}
					else
					{
						if (vector5.y > vector7.y)
						{
							vector4 = forward * vector7.y + right * vector7.x;
							num3 = num * (float)Mathf.CeilToInt(num4 / num);
							list.Add(vector7 * num2);
							list2.Add(center + vector4 * radius2);
							list3.Add(vector7 * num2);
							list4.Add(center + vector4 * radius2);
						}
						while (num3 < cutFrom)
						{
							vector3 = new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3));
							vector4 = forward * vector3.y + right * vector3.x;
							float num6 = vector5.y / vector3.y;
							num7 = ((vector6.y / vector3.y < num2) ? num2 : (vector6.y / vector3.y));
							num3 += num;
							list.Add(vector3 * num6);
							list2.Add(center + vector4 * (radius1 * num6));
							list3.Add(vector3 * num7);
							list4.Add(center + vector4 * (radius1 * num7));
						}
					}
					vector4 = forward * vector5.y + right * vector5.x;
					num7 = ((vector6.y / vector5.y < num2 || isSector) ? num2 : (vector6.y / vector5.y));
					list.Add(vector5);
					list2.Add(center + vector4 * radius1);
					list3.Add(vector5 * num7);
					list4.Add(center + vector4 * (radius1 * num7));
					if (cutTo < MathF.PI / 2f)
					{
						if (num5 > cutFrom && !isSector)
						{
							while (num3 < num5)
							{
								vector3 = new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3));
								vector4 = forward * vector3.y + right * vector3.x;
								num7 = ((vector6.y / vector3.y < num2) ? num2 : (vector6.y / vector3.y));
								num3 += num;
								list.Add(vector3);
								list2.Add(center + vector4 * radius1);
								list3.Add(vector3 * num7);
								list4.Add(center + vector4 * (radius1 * num7));
							}
							vector4 = forward * vector8.y + right * vector8.x;
							num7 = ((vector6.y / vector8.y < num2) ? num2 : (vector6.y / vector8.y));
							list.Add(vector8);
							list2.Add(center + vector4 * radius1);
							list3.Add(vector8 * num7);
							list4.Add(center + vector4 * (radius1 * num7));
						}
						while (num3 < cutTo)
						{
							vector3 = new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3));
							vector4 = forward * vector3.y + right * vector3.x;
							num7 = ((vector6.y / vector3.y < num2 || isSector) ? num2 : (vector6.y / vector3.y));
							num3 += num;
							list.Add(vector3);
							list2.Add(center + vector4 * radius1);
							list3.Add(vector3 * num7);
							list4.Add(center + vector4 * (radius1 * num7));
						}
						vector4 = forward * vector6.y + right * vector6.x;
						num7 = (isSector ? num2 : 1f);
						list.Add(vector6);
						list2.Add(center + vector4 * radius1);
						list3.Add(vector6 * num7);
						list4.Add(center + vector4 * (radius1 * num7));
					}
					else
					{
						while (num3 < cutTo)
						{
							vector3 = new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3));
							vector4 = forward * vector3.y + right * vector3.x;
							num3 += num;
							list.Add(vector3);
							list2.Add(center + vector4 * radius1);
							list3.Add(vector3 * num2);
							list4.Add(center + vector4 * radius2);
						}
						vector4 = forward * vector6.y + right * vector6.x;
						list.Add(vector6);
						list2.Add(center + vector4 * radius1);
						list3.Add(vector6 * num2);
						list4.Add(center + vector4 * radius2);
						if (!isSector)
						{
							while (num3 < num5)
							{
								vector3 = new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3));
								vector4 = forward * vector3.y + right * vector3.x;
								float num6 = vector6.y / vector3.y;
								num3 += num;
								list.Add(vector3);
								list2.Add(center + vector4 * (radius1 * num6));
								list3.Add(vector3 * num2);
								list4.Add(center + vector4 * radius2);
							}
							if (vector6.y < vector8.y)
							{
								vector4 = forward * vector8.y + right * vector8.x;
								list.Add(vector8 * num2);
								list2.Add(center + vector4 * radius2);
								list3.Add(vector8 * num2);
								list4.Add(center + vector4 * radius2);
							}
						}
					}
				}
				else
				{
					num3 = num * (float)(Mathf.FloorToInt(cutFrom / num) + 1);
					vector4 = forward * vector5.y + right * vector5.x;
					float num7 = (isSector ? num2 : 1f);
					list.Add(vector5);
					list2.Add(center + vector4 * radius1);
					list3.Add(vector5 * num7);
					list4.Add(center + vector4 * (radius1 * num7));
					if (cutTo > num4 && !isSector)
					{
						float num6;
						while (num3 < num4)
						{
							vector3 = new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3));
							vector4 = forward * vector3.y + right * vector3.x;
							num6 = ((vector6.y > vector3.y) ? 1f : (vector6.y / vector3.y));
							num7 = vector5.y / vector3.y;
							num3 += num;
							list.Add(vector3);
							list2.Add(center + vector4 * (radius1 * num6));
							list3.Add(vector3 * num7);
							list4.Add(center + vector4 * (radius1 * num7));
						}
						vector4 = forward * vector7.y + right * vector7.x;
						num6 = ((vector6.y / vector7.y > 1f) ? 1f : (vector6.y / vector7.y));
						list.Add(vector5);
						list2.Add(center + vector4 * (radius1 * num6));
						list3.Add(vector5);
						list4.Add(center + vector4 * radius2);
					}
					while (num3 < cutTo)
					{
						vector3 = new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3));
						vector4 = forward * vector3.y + right * vector3.x;
						float num6 = ((vector6.y > vector3.y) ? 1f : (vector6.y / vector3.y));
						num7 = ((vector5.y / vector3.y < num2 || isSector) ? num2 : (vector5.y / vector3.y));
						num3 += num;
						list.Add(vector3);
						list2.Add(center + vector4 * (radius1 * num6));
						list3.Add(vector3 * num7);
						list4.Add(center + vector4 * (radius1 * num7));
					}
					vector4 = forward * vector6.y + right * vector6.x;
					num7 = ((vector5.y / vector6.y < num2 || isSector) ? num2 : (vector5.y / vector6.y));
					list.Add(vector6);
					list2.Add(center + vector4 * radius1);
					list3.Add(vector6 * num2);
					list4.Add(center + vector4 * (radius1 * num7));
					if (!isSector)
					{
						while (num3 < num5)
						{
							vector3 = new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3));
							vector4 = forward * vector3.y + right * vector3.x;
							float num6 = ((vector6.y > vector3.y) ? 1f : (vector6.y / vector3.y));
							num7 = ((vector5.y / vector3.y < num2) ? num2 : (vector5.y / vector3.y));
							num3 += num;
							list.Add(vector3);
							list2.Add(center + vector4 * (radius1 * num6));
							list3.Add(vector3 * num7);
							list4.Add(center + vector4 * (radius1 * num7));
						}
						if (vector6.y < vector8.y)
						{
							vector4 = forward * vector8.y + right * vector8.x;
							list.Add(vector8 * num2);
							list2.Add(center + vector4 * radius2);
							list3.Add(vector8 * num2);
							list4.Add(center + vector4 * radius2);
						}
					}
				}
			}
			else
			{
				for (int i = 0; i <= sides; i++)
				{
					Vector2 vector9 = new Vector2(Mathf.Sin(num * (float)i), 0f - Mathf.Cos(num * (float)i));
					Vector3 vector10 = forward * vector9.y + right * vector9.x;
					list.Add(vector9);
					list2.Add(center + vector10 * radius1);
					list3.Add(vector9 * num2);
					list4.Add(center + vector10 * radius2);
				}
			}
			Vector2[] array = (generateUV ? list.ToArray() : null);
			Vector2[] array2 = (generateUV ? list3.ToArray() : null);
			if (realWorldMapSize)
			{
				uvTiling *= radius1 * 2f;
			}
			if (flip)
			{
				vector = -vector;
				list2.Reverse();
				list4.Reverse();
				if (array != null)
				{
					array = array.Reverse().ToArray();
					array2 = array2.Reverse().ToArray();
				}
			}
			CreateRing(list2.ToArray(), list4.ToArray(), array, array2, center + vector2, -vector, seg, uvOffset, uvTiling, centerUVOffset);
		}

		protected void CreateRing(Vector3[] points, Vector3[] points2, Vector2[] uvs, Vector2[] uvs2, Vector3 center, Vector3 normal, int seg, Vector2 uvOffset, Vector2 uvTiling, float centerUVOffset = 0f)
		{
			int count = m_vertices.Count;
			if (uvs != null)
			{
				Vector2 vector = new Vector2(0.5f, 0.5f + centerUVOffset);
				for (int i = 0; i < points.Length; i++)
				{
					Vector3 vector2 = (points[i] - points2[i]) / seg;
					Vector2 vector3 = uvs2[i] * 0.5f;
					vector3.y -= centerUVOffset;
					vector3.x *= uvTiling.x;
					vector3.y *= uvTiling.y;
					Vector2 vector4 = (uvs[i] - uvs2[i]) * 0.5f;
					vector4.y -= centerUVOffset;
					vector4.x *= uvTiling.x / (float)seg;
					vector4.y *= uvTiling.y / (float)seg;
					for (int j = 0; j <= seg; j++)
					{
						m_vertices.Add(points2[i] + vector2 * j);
						m_normals.Add(normal);
						m_uv.Add(vector + uvOffset + vector3 + vector4 * j);
					}
				}
			}
			else
			{
				for (int k = 0; k < points.Length; k++)
				{
					Vector3 vector5 = (points[k] - points2[k]) / seg;
					for (int l = 0; l <= seg; l++)
					{
						m_vertices.Add(points2[k] + vector5 * l);
						m_normals.Add(normal);
					}
				}
			}
			for (int m = 0; m < points.Length - 1; m++)
			{
				for (int n = 0; n < seg; n++)
				{
					int[] array = new int[4]
					{
						count + (seg + 1) * m + n,
						count + (seg + 1) * m + (n + 1),
						count + (seg + 1) * (m + 1) + (n + 1),
						count + (seg + 1) * (m + 1) + n
					};
					m_triangles.Add(array[0]);
					m_triangles.Add(array[1]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[2]);
					m_triangles.Add(array[3]);
					m_triangles.Add(array[0]);
				}
			}
		}

		protected void CreateTorus(Vector3 center, Vector3 forward, Vector3 right, float radius1, float radius2, int sides, int seg, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, bool flip, bool smooth, float sectionSliceFrom = 0f, float sectionSliceTo = 360f)
		{
			CreateTorus(center, forward, right, radius1, radius2, sides, seg, sliceOn, sliceFrom, sliceTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip, smooth, sectionSliceFrom, sectionSliceTo);
		}

		protected void CreateTorus(Vector3 center, Vector3 forward, Vector3 right, float radius1, float radius2, int sides, int seg, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth, float sectionSliceFrom, float sectionSliceTo)
		{
			if (radius2 < 0.0001f)
			{
				return;
			}
			radius1 += 1E-05f;
			Vector3 normalized = Vector3.Cross(forward, right).normalized;
			sectionSliceFrom = sectionSliceFrom * (MathF.PI / 180f) - MathF.PI / 2f;
			sectionSliceTo = sectionSliceTo * (MathF.PI / 180f) - MathF.PI / 2f;
			float num = (sectionSliceTo - sectionSliceFrom) / (float)seg;
			Vector2[] array = new Vector2[seg + 1];
			for (int i = 0; i <= seg; i++)
			{
				float f = sectionSliceFrom + num * (float)i;
				array[i].x = Mathf.Sin(f);
				array[i].y = 0f - Mathf.Cos(f);
			}
			uvTiling.y *= (sectionSliceTo - sectionSliceFrom) / (MathF.PI * 2f);
			Vector3[] array2 = new Vector3[sides + 1];
			Vector3[][] array3 = new Vector3[sides + 1][];
			if (!sliceOn)
			{
				sliceFrom = 0f;
				sliceTo = 360f;
			}
			float num2 = sliceFrom * (MathF.PI / 180f);
			float num3 = (sliceTo - sliceFrom) * (MathF.PI / 180f);
			float num4 = num3 / (float)sides;
			for (int j = 0; j <= sides; j++)
			{
				float f2 = num2 + num4 * (float)j;
				float num5 = Mathf.Sin(f2);
				float num6 = Mathf.Cos(f2);
				array2[j] = center + (forward * num6 + right * num5) * radius1;
				array3[j] = new Vector3[seg + 1];
				for (int k = 0; k <= seg; k++)
				{
					array3[j][k] = array2[j] + (normalized * array[k].y + (array2[j] - center) / radius1 * array[k].x) * radius2;
				}
			}
			if (realWorldMapSize)
			{
				uvTiling.x *= num3 * (radius1 + radius2);
				uvTiling.y *= MathF.PI * 2f * radius2;
			}
			if (flip)
			{
				array3 = array3.Reverse().ToArray();
				array2 = array2.Reverse().ToArray();
			}
			CreateTorus(array3, array2, seg, generateUV, uvOffset, uvTiling, flip, smooth);
		}

		protected void CreateTorus(Vector3[][] points, Vector3[] centers, int seg, bool generateUV, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth)
		{
			uvTiling.x *= -1f;
			if (smooth)
			{
				int count = m_vertices.Count;
				float num = (flip ? (-1f) : 1f);
				if (generateUV)
				{
					Vector2 vector = Vector2.right * uvTiling.x / (points.Length - 1);
					Vector2 vector2 = Vector2.up * uvTiling.y / (points[0].Length - 1);
					for (int i = 0; i < points.Length; i++)
					{
						for (int j = 0; j < points[i].Length; j++)
						{
							m_vertices.Add(points[i][j]);
							m_normals.Add((points[i][j] - centers[i]).normalized * num);
							m_uv.Add(uvOffset + vector * i + vector2 * j);
						}
					}
				}
				else
				{
					for (int k = 0; k < points.Length; k++)
					{
						for (int l = 0; l < points[k].Length; l++)
						{
							m_vertices.Add(points[k][l]);
							m_normals.Add((points[k][l] - centers[k]).normalized * num);
						}
					}
				}
				for (int m = 0; m < points.Length - 1; m++)
				{
					for (int n = 0; n < points[m].Length - 1; n++)
					{
						int[] array = new int[4]
						{
							count + points[m].Length * (m + 1) + n,
							count + points[m].Length * (m + 1) + (n + 1),
							count + points[m].Length * m + (n + 1),
							count + points[m].Length * m + n
						};
						m_triangles.Add(array[0]);
						m_triangles.Add(array[1]);
						m_triangles.Add(array[2]);
						m_triangles.Add(array[2]);
						m_triangles.Add(array[3]);
						m_triangles.Add(array[0]);
					}
				}
				return;
			}
			if (generateUV)
			{
				Vector2[][] array2 = new Vector2[points.Length][];
				Vector2 vector3 = Vector2.right * uvTiling.x / (points.Length - 1);
				Vector2 vector4 = Vector2.up * uvTiling.y / (points[0].Length - 1);
				for (int num2 = 0; num2 < points.Length; num2++)
				{
					array2[num2] = new Vector2[points[num2].Length];
					for (int num3 = 0; num3 < points[num2].Length; num3++)
					{
						array2[num2][num3] = uvOffset + vector3 * num2 + vector4 * num3;
					}
				}
				for (int num4 = 0; num4 < points.Length - 1; num4++)
				{
					for (int num5 = 0; num5 < points[num4].Length - 1; num5++)
					{
						CreateQuad(points[num4 + 1][num5], points[num4 + 1][num5 + 1], points[num4][num5 + 1], points[num4][num5], array2[num4 + 1][num5], array2[num4 + 1][num5 + 1], array2[num4][num5 + 1], array2[num4][num5]);
					}
				}
				return;
			}
			for (int num6 = 0; num6 < points.Length - 1; num6++)
			{
				for (int num7 = 0; num7 < points[num6].Length - 1; num7++)
				{
					CreateQuad(points[num6 + 1][num7], points[num6 + 1][num7 + 1], points[num6][num7 + 1], points[num6][num7]);
				}
			}
		}

		protected void CreateCylinder(Vector3 center, Vector3 forward, Vector3 right, float height, float radius, int sides, int segHeight, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, bool flip, bool smooth)
		{
			CreateCylinder(center, forward, right, height, radius, sides, segHeight, sliceOn, sliceFrom, sliceTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip, smooth);
		}

		protected void CreateCylinder(Vector3 center, Vector3 forward, Vector3 right, float height, float radius, int sides, int segHeight, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth)
		{
			if (!(radius < 0.0001f))
			{
				Vector3 normalized = Vector3.Cross(forward, right).normalized;
				float num = height * 0.5f;
				Vector2[] array = new Vector2[sides + 1];
				Vector3[] array2 = new Vector3[sides + 1];
				Vector3[] array3 = new Vector3[sides + 1];
				Vector3 vector = center - normalized * num;
				Vector3 vector2 = center + normalized * num;
				if (!sliceOn)
				{
					sliceFrom = 0f;
					sliceTo = 360f;
				}
				float num2 = sliceFrom * (MathF.PI / 180f);
				float num3 = (sliceTo - sliceFrom) * (MathF.PI / 180f);
				float num4 = num3 / (float)sides;
				for (int i = 0; i <= sides; i++)
				{
					float f = num2 + num4 * (float)i;
					array[i].x = Mathf.Sin(f);
					array[i].y = Mathf.Cos(f);
					Vector3 vector3 = (forward * array[i].y + right * array[i].x) * radius;
					array2[i] = vector + vector3;
					array3[i] = vector2 + vector3;
				}
				if (realWorldMapSize)
				{
					uvTiling.x *= num3 * radius;
					uvTiling.y *= height;
				}
				if (flip)
				{
					array2 = array2.Reverse().ToArray();
					array3 = array3.Reverse().ToArray();
				}
				CreateCylinder(array2, array3, vector, vector2, segHeight, generateUV, uvOffset, uvTiling, flip, smooth);
			}
		}

		protected void CreateCylinder(Vector3[] pDown, Vector3[] pUp, Vector3 centerDown, Vector3 centerUp, int seg, bool generateUV, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth)
		{
			uvTiling.x *= -1f;
			if (smooth)
			{
				int count = m_vertices.Count;
				Vector3 vector = (centerUp - centerDown) / seg;
				float num = (flip ? (-1f) : 1f);
				if (generateUV)
				{
					Vector2 vector2 = Vector2.right * uvTiling.x / (pDown.Length - 1);
					Vector2 vector3 = Vector2.up * uvTiling.y / seg;
					for (int i = 0; i < pDown.Length; i++)
					{
						Vector3 item = (pDown[i] - centerDown + (pUp[i] - centerUp)).normalized * num;
						for (int j = 0; j <= seg; j++)
						{
							m_vertices.Add(pDown[i] + vector * j);
							m_normals.Add(item);
							m_uv.Add(uvOffset + vector2 * i + vector3 * j);
						}
					}
				}
				else
				{
					for (int k = 0; k < pDown.Length; k++)
					{
						Vector3 vector4 = (pDown[k] - centerDown + (pUp[k] - centerUp)).normalized * num;
						if (flip)
						{
							vector4 = -vector4;
						}
						for (int l = 0; l <= seg; l++)
						{
							m_vertices.Add(pDown[k] + vector * l);
							m_normals.Add(vector4);
						}
					}
				}
				for (int m = 0; m < pDown.Length - 1; m++)
				{
					for (int n = 0; n < seg; n++)
					{
						int[] array = new int[4]
						{
							count + (seg + 1) * (m + 1) + n,
							count + (seg + 1) * (m + 1) + (n + 1),
							count + (seg + 1) * m + (n + 1),
							count + (seg + 1) * m + n
						};
						m_triangles.Add(array[0]);
						m_triangles.Add(array[1]);
						m_triangles.Add(array[2]);
						m_triangles.Add(array[2]);
						m_triangles.Add(array[3]);
						m_triangles.Add(array[0]);
					}
				}
			}
			else
			{
				float num2 = uvTiling.x / (float)(pDown.Length - 1);
				float num3 = 1f / (float)(pDown.Length - 1);
				for (int num4 = 0; num4 < pDown.Length - 1; num4++)
				{
					Vector3 normalized = Vector3.Cross(pUp[num4] - pDown[num4 + 1], pDown[num4] - pUp[num4 + 1]).normalized;
					CreatePlane(pDown[num4 + 1], pUp[num4 + 1], pUp[num4], pDown[num4], normalized, 1, seg, generateUV, new Vector2(uvOffset.x + num2 * (float)(num4 + 1), uvOffset.y), new Vector2((0f - uvTiling.x) * num3, uvTiling.y));
				}
			}
		}

		protected void CreateCone(Vector3 center, Vector3 forward, Vector3 right, float height, float radius1, float radius2, int sides, int segHeight, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, bool flip, bool smooth)
		{
			Vector3 normalized = Vector3.Cross(forward, right).normalized;
			Vector3 vector = center - normalized * height * 0.5f;
			Vector3 centerUp = vector + normalized * height;
			CreateCone(vector, centerUp, forward, right, height, radius1, radius2, sides, segHeight, sliceOn, sliceFrom, sliceTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip, smooth);
		}

		protected void CreateCone(Vector3 center, Vector3 forward, Vector3 right, float height, float radius1, float radius2, int sides, int segHeight, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth)
		{
			Vector3 normalized = Vector3.Cross(forward, right).normalized;
			Vector3 vector = center - normalized * height * 0.5f;
			Vector3 centerUp = vector + normalized * height;
			CreateCone(vector, centerUp, forward, right, height, radius1, radius2, sides, segHeight, sliceOn, sliceFrom, sliceTo, generateUV, realWorldMapSize, uvOffset, uvTiling, flip, smooth);
		}

		protected void CreateCone(Vector3 centerDown, Vector3 centerUp, Vector3 forward, Vector3 right, float height, float radius1, float radius2, int sides, int segHeight, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, bool flip, bool smooth)
		{
			CreateCone(centerDown, centerUp, forward, right, height, radius1, radius2, sides, segHeight, sliceOn, sliceFrom, sliceTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip, smooth);
		}

		protected void CreateCone(Vector3 centerDown, Vector3 centerUp, Vector3 forward, Vector3 right, float height, float radius1, float radius2, int sides, int segHeight, bool sliceOn, float sliceFrom, float sliceTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth)
		{
			if (!(radius1 + radius2 < 0.0001f))
			{
				Vector3 normalized = Vector3.Cross(forward, right).normalized;
				Vector2[] array = new Vector2[sides + 1];
				Vector3[] array2 = new Vector3[sides + 1];
				Vector3[] array3 = new Vector3[sides + 1];
				if (!sliceOn)
				{
					sliceFrom = 0f;
					sliceTo = 360f;
				}
				float num = sliceFrom * (MathF.PI / 180f);
				float num2 = (sliceTo - sliceFrom) * (MathF.PI / 180f);
				float num3 = num2 / (float)sides;
				for (int i = 0; i <= sides; i++)
				{
					float f = num + num3 * (float)i;
					array[i].x = Mathf.Sin(f);
					array[i].y = Mathf.Cos(f);
					Vector3 vector = forward * array[i].y + right * array[i].x;
					array2[i] = centerDown + vector * radius1;
					array3[i] = centerUp + vector * radius2;
				}
				if (realWorldMapSize)
				{
					uvTiling.x *= num2 * (radius1 + radius2) * 0.5f;
					uvTiling.y *= height;
				}
				if (flip)
				{
					array2 = array2.Reverse().ToArray();
					array3 = array3.Reverse().ToArray();
				}
				CreateCone(array2, array3, centerDown, centerUp, normalized, segHeight, generateUV, uvOffset, uvTiling, flip, smooth);
			}
		}

		protected void CreateCone(Vector3[] pDown, Vector3[] pUp, Vector3 centerDown, Vector3 centerUp, Vector3 up, int seg, bool generateUV, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth)
		{
			uvTiling.x *= -1f;
			if (smooth)
			{
				int count = m_vertices.Count;
				float num = (flip ? (-1f) : 1f);
				if (generateUV)
				{
					Vector2 vector = Vector2.right * uvTiling.x / (pDown.Length - 1);
					Vector2 vector2 = Vector2.up * uvTiling.y / seg;
					for (int i = 0; i < pDown.Length; i++)
					{
						Vector3 vector3 = pUp[i] - pDown[i];
						Vector3 vector4 = pDown[i] - centerDown + (pUp[i] - centerUp);
						vector4 = (vector4 + up * vector4.magnitude * PointLineProjectionn(vector3, -vector4) / PointLineProjectionn(vector3, up)).normalized * num;
						vector3 /= (float)seg;
						for (int j = 0; j <= seg; j++)
						{
							m_vertices.Add(pDown[i] + vector3 * j);
							m_normals.Add(vector4);
							m_uv.Add(uvOffset + vector * i + vector2 * j);
						}
					}
				}
				else
				{
					for (int k = 0; k < pDown.Length; k++)
					{
						Vector3 vector5 = pUp[k] - pDown[k];
						Vector3 vector6 = pDown[k] - centerDown + (pUp[k] - centerUp);
						vector6 = (vector6 + up * vector6.magnitude * PointLineProjectionn(vector5, -vector6) / PointLineProjectionn(vector5, up)).normalized * num;
						vector5 /= (float)seg;
						for (int l = 0; l <= seg; l++)
						{
							m_vertices.Add(pDown[k] + vector5 * l);
							m_normals.Add(vector6);
						}
					}
				}
				for (int m = 0; m < pDown.Length - 1; m++)
				{
					for (int n = 0; n < seg; n++)
					{
						int[] array = new int[4]
						{
							count + (seg + 1) * (m + 1) + n,
							count + (seg + 1) * (m + 1) + (n + 1),
							count + (seg + 1) * m + (n + 1),
							count + (seg + 1) * m + n
						};
						m_triangles.Add(array[0]);
						m_triangles.Add(array[1]);
						m_triangles.Add(array[2]);
						m_triangles.Add(array[2]);
						m_triangles.Add(array[3]);
						m_triangles.Add(array[0]);
					}
				}
			}
			else
			{
				float num2 = uvTiling.x / (float)(pDown.Length - 1);
				float num3 = 1f / (float)(pDown.Length - 1);
				for (int num4 = 0; num4 < pDown.Length - 1; num4++)
				{
					Vector3 normalized = Vector3.Cross(pUp[num4] - pDown[num4 + 1], pDown[num4] - pUp[num4 + 1]).normalized;
					CreateTrapezoid(pDown[num4 + 1], pUp[num4 + 1], pUp[num4], pDown[num4], normalized, 1, seg, generateUV, new Vector2(uvOffset.x + num2 * (float)(num4 + 1), uvOffset.y), new Vector2((0f - uvTiling.x) * num3, uvTiling.y));
				}
			}
		}

		protected void CreateSphere(Vector3 center, Vector3 forward, Vector3 right, float radius, int sides, int seg, bool sliceOn, float sliceFrom, float sliceTo, bool hemiSphere, float cutFrom, float cutTo, bool generateUV, bool realWorldMapSize, bool flip, bool smooth)
		{
			CreateSphere(center, forward, right, radius, sides, seg, sliceOn, sliceFrom, sliceTo, hemiSphere, cutFrom, cutTo, generateUV, realWorldMapSize, Vector2.zero, Vector2.one, flip, smooth);
		}

		protected void CreateSphere(Vector3 center, Vector3 forward, Vector3 right, float radius, int sides, int seg, bool sliceOn, float sliceFrom, float sliceTo, bool hemiSphere, float cutFrom, float cutTo, bool generateUV, bool realWorldMapSize, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth)
		{
			if (radius < 0.0001f)
			{
				return;
			}
			Vector3 normalized = Vector3.Cross(forward, right).normalized;
			float num = MathF.PI / (float)seg;
			List<Vector2> list = new List<Vector2>();
			Vector3[][] array = new Vector3[sides + 1][];
			float rFrom = 1f;
			float rTo = 1f;
			if (hemiSphere)
			{
				int num2 = Mathf.FloorToInt(cutFrom / num) + 1;
				int num3 = Mathf.CeilToInt(cutTo / num) - 1;
				rFrom = cutFrom / num - (float)(num2 - 1);
				rTo = cutTo / num - (float)num3;
				list.Add(new Vector2(Mathf.Sin(cutFrom), 0f - Mathf.Cos(cutFrom)));
				for (int i = num2; i <= num3; i++)
				{
					list.Add(new Vector2(Mathf.Sin(num * (float)i), 0f - Mathf.Cos(num * (float)i)));
				}
				list.Add(new Vector2(Mathf.Sin(cutTo), 0f - Mathf.Cos(cutTo)));
				uvTiling.y *= num * (float)(num3 - num2 + 2) / MathF.PI;
				uvOffset.y += num * (float)(num2 - 1) / MathF.PI;
			}
			else
			{
				cutFrom = 0f;
				cutTo = MathF.PI;
				for (int j = 0; j <= seg; j++)
				{
					list.Add(new Vector2(Mathf.Sin(num * (float)j), 0f - Mathf.Cos(num * (float)j)));
				}
			}
			if (!sliceOn)
			{
				sliceFrom = 0f;
				sliceTo = 360f;
			}
			float num4 = sliceFrom * (MathF.PI / 180f);
			float num5 = (sliceTo - sliceFrom) * (MathF.PI / 180f);
			float num6 = num5 / (float)sides;
			for (int k = 0; k <= sides; k++)
			{
				float f = num4 + num6 * (float)k;
				Vector3 vector = (right * Mathf.Sin(f) + forward * Mathf.Cos(f)) * radius;
				Vector3 vector2 = normalized * radius;
				array[k] = new Vector3[list.Count];
				for (int l = 0; l < list.Count; l++)
				{
					array[k][l] = center + vector * list[l].x + vector2 * list[l].y;
				}
			}
			if (realWorldMapSize)
			{
				uvTiling.x *= num5 * radius;
				uvTiling.y *= MathF.PI * radius;
			}
			if (flip)
			{
				array = array.Reverse().ToArray();
			}
			CreateSphere(array, center, generateUV, uvOffset, uvTiling, flip, smooth, rFrom, rTo);
		}

		protected void CreateSphere(Vector3[][] points, Vector3 center, bool generateUV, Vector2 uvOffset, Vector2 uvTiling, bool flip, bool smooth, float rFrom, float rTo)
		{
			uvTiling.x *= -1f;
			if (smooth)
			{
				int count = m_vertices.Count;
				float num = (flip ? (-1f) : 1f);
				if (generateUV)
				{
					Vector2 vector = Vector2.right * uvTiling.x / (points.Length - 1);
					Vector2 vector2 = Vector2.up * uvTiling.y / (points[0].Length - 1);
					for (int i = 0; i < points.Length; i++)
					{
						m_vertices.Add(points[i][0]);
						m_normals.Add((points[i][0] - center).normalized * num);
						m_uv.Add(uvOffset + vector * i + vector2 * rFrom);
						for (int j = 1; j < points[i].Length - 1; j++)
						{
							m_vertices.Add(points[i][j]);
							m_normals.Add((points[i][j] - center).normalized * num);
							m_uv.Add(uvOffset + vector * i + vector2 * j);
						}
						m_vertices.Add(points[i][points[i].Length - 1]);
						m_normals.Add((points[i][points[i].Length - 1] - center).normalized * num);
						m_uv.Add(uvOffset + vector * i + vector2 * ((float)(points[i].Length - 2) + rTo));
					}
				}
				else
				{
					for (int k = 0; k < points.Length; k++)
					{
						for (int l = 0; l < points[k].Length; l++)
						{
							m_vertices.Add(points[k][l]);
							m_normals.Add((points[k][l] - center).normalized * num);
						}
					}
				}
				for (int m = 0; m < points.Length - 1; m++)
				{
					for (int n = 0; n < points[m].Length - 1; n++)
					{
						int[] array = new int[4]
						{
							count + points[m].Length * (m + 1) + n,
							count + points[m].Length * (m + 1) + (n + 1),
							count + points[m].Length * m + (n + 1),
							count + points[m].Length * m + n
						};
						m_triangles.Add(array[0]);
						m_triangles.Add(array[1]);
						m_triangles.Add(array[2]);
						m_triangles.Add(array[2]);
						m_triangles.Add(array[3]);
						m_triangles.Add(array[0]);
					}
				}
				return;
			}
			if (generateUV)
			{
				Vector2[][] array2 = new Vector2[points.Length][];
				Vector2 vector3 = Vector2.right * uvTiling.x / (points.Length - 1);
				Vector2 vector4 = Vector2.up * uvTiling.y / (points[0].Length - 1);
				for (int num2 = 0; num2 < points.Length; num2++)
				{
					array2[num2] = new Vector2[points[num2].Length];
					array2[num2][0] = uvOffset + vector3 * num2 + vector4 * rFrom;
					for (int num3 = 1; num3 < points[num2].Length - 1; num3++)
					{
						array2[num2][num3] = uvOffset + vector3 * num2 + vector4 * num3;
					}
					array2[num2][points[num2].Length - 1] = uvOffset + vector3 * num2 + vector4 * ((float)(points[num2].Length - 2) + rTo);
				}
				for (int num4 = 0; num4 < points.Length - 1; num4++)
				{
					for (int num5 = 0; num5 < points[num4].Length - 1; num5++)
					{
						CreateQuad(points[num4 + 1][num5], points[num4 + 1][num5 + 1], points[num4][num5 + 1], points[num4][num5], array2[num4 + 1][num5], array2[num4 + 1][num5 + 1], array2[num4][num5 + 1], array2[num4][num5]);
					}
				}
				return;
			}
			for (int num6 = 0; num6 < points.Length - 1; num6++)
			{
				for (int num7 = 0; num7 < points[num6].Length - 1; num7++)
				{
					CreateQuad(points[num6 + 1][num7], points[num6 + 1][num7 + 1], points[num6][num7 + 1], points[num6][num7]);
				}
			}
		}

		protected abstract void CreateMesh();

		public void Apply()
		{
			if (m_mesh == null)
			{
				m_mesh = new Mesh();
			}
			m_rotation = Quaternion.Euler(rotation);
			CreateMesh();
			m_mesh.Clear();
			m_mesh.SetVertices(m_vertices);
			m_mesh.SetNormals(m_normals);
			m_mesh.SetTriangles(m_triangles, 0);
			m_mesh.SetUVs(0, m_uv);
			if (m_meshFilter == null)
			{
				m_meshFilter = GetComponent<MeshFilter>();
			}
			if (m_meshFilter != null)
			{
				m_meshFilter.sharedMesh = m_mesh;
			}
			MeshCollider component = GetComponent<MeshCollider>();
			if (component != null)
			{
				component.sharedMesh = m_mesh;
			}
			m_vertices.Clear();
			m_triangles.Clear();
			m_normals.Clear();
			m_uv.Clear();
			m_dirty = false;
		}

		private void OnDestroy()
		{
			if (m_mesh != null)
			{
				UnityEngine.Object.Destroy(m_mesh);
			}
		}

		private void Awake()
		{
			m_meshFilter = GetComponent<MeshFilter>();
			m_mesh = new Mesh();
		}

		private void Start()
		{
			Apply();
		}

		private void Reset()
		{
			Apply();
		}

		private void OnValidate()
		{
			m_dirty = true;
		}

		public GameObject CreateInstance()
		{
			return ProceduralPrimitives.CreateInstance(this);
		}

		public void ForceRecreateMesh()
		{
			m_mesh = null;
			Apply();
		}
	}
}
